<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>基础语法1：插值表达式、data、methods、computed和watch</title>
    <script src="https://unpkg.com/vue@3"></script>
</head>
<body>
    <div id="app">
        <h1>知识点1：插值表达式</h1>
            <p>我是变量：{{msg}}</p>
            <!-- {{}}插值表达式符号 -->
            <p>我是表达式：{{5*6-10}}</p>
            <p>我是表达式：{{num+1}}</p>
            <p>我是条件运算符：{{1+1==2?1:0}}</p>
            <p>我是函数：{{add()}}</p>
        <h1>知识点2：data </h1>
            <h3>我们在控制台中可以通过实例名.$data的形式来访问或修改data数据。</h3>
        <h1>知识点3：methods</h1>
            <h3>方法名(){} 或者 方法名：function(){}</h3>
            <p>{{sub(1000000)}}</p>
        <h1>知识点4：computed 计算属性</h1>
            <h3>遇到复杂逻辑是，vue.js提倡我们使用computed计算属性。
                在计算属性里面，我们可以完成各种比较复杂的逻辑，包括逻辑运算，函数调用等，最后只要返回一个结果即可。
            </h3>
            <p>{{rev}}</p>
            <p>{{revMethod()}}</p>
            <p>{{double}}</p>
            <h3>计算属性是基于其依赖的变量进行缓存的，计算属性只有在它相关的依赖发生改变的时候才会重新求值。
                而方法则是每次页面重新渲染时都会进行计算
            </h3>
            <h3>通常我们的计算属性是只读的，不进行修改</h3>
            <button @click="double=100">我们来尝试下修改计算属性的值</button>
            <h3>通过传入一个包含get和set的函数的对象，可以得到一个可读可写的计算属性</h3>
            <h3>绝大多数情况下，只会使用默认的get函数来读取一个计算属性，在实际业务中，很少使用到set。
                因此，我们在使用时，通常直接使用默认写法，不必将get和set都声明
            </h3>
            <h1>知识点5 watch 监听</h1>
                <h3>当我们需要在某种状态变化时，执行一些其他的操作，watch具有状态监听的动态，
                    只要监听到当前vue实例中的数据变化，就会调用当前数据所绑定的方法。
                </h3>
                <h4>1.函数侦听器：在watch选项中声明的函数即为函数式侦听器，其中函数名就是我们要侦听的数据源</h4>
                <!-- 在后台中输入appConn.$data.grade=100 或 50来体会一下监听 -->
                <h4>2.对象侦听器：在watch选项中声明的对象即为对象侦听器，其中对象名就是我们要侦听的数据源</h4>
                <h4>如果监听的需求比较简单，也不会涉及日后的扩展，就可以直接使用函数式监听器
                    如果监听比较复杂，比如，监听有多层对象，或者需要用到immediate属性，或者方便日后扩展，就用对象式监听器
                </h4>
    </div>
</body>
</html>

<script>
    const appConn = Vue.createApp({
        //data里面放置全部的数据，包括变量、对象等
        data(){
            return{
                msg:'我的第一个vue页面',
                num:1,
                grade:60,
                users:{
                    name:'zhangsan',
                    age:19
                }
            }
        },
        //methods里面放置全部的方法
        methods:{
            add(){
                return this.num + 100
            },
            sub:function(val){
                return this.num - val
            },
            revMethod(){
                console.log("我是方法，我被调用了一次");
                return this.msg.split('').reverse().join('')
            }
        },
        computed:{
            rev(){
                console.log("我是计算属性，我被调用了一次");
                return this.msg.split('').reverse().join('')
            },
            // double(){
            //     return this.num * 2
            // }
            double:{
                get:function(){
                    return this.num * 2
                },
                set:function(val){
                    this.num = val/2
                }
            }
        },
        watch:{
            //函数式侦听器
            grade(newData,oldData){
                console.log('改变前的数据：' + oldData);
                console.log('改变后的数据：' + newData);
                if(newData>oldData)
                    console.log("你很棒，有进步！");
                else
                    console.log("你怎么能越考越差呢？");

            },
            //对象式侦听器
            'users.age':{
                handler(newData,oldData){
                    console.log('改变前的年龄' + oldData);
                    console.log('改变后的年龄' + newData);
                    if(newData>=120 || newData<0)
                        console.log("你确定你输入的是年龄？");
                }
            }
        }
    }).mount("#app")
</script>